跳到主要内容

Julia 宏

阐述

接收若干个表达式并返回一个表达式的函数,且返回的表达式直接被编译,而不是等待在运行时被 eval。可以用 macroexpand 函数或 @macroexpand 宏来查看宏被展开得到的具体内容。

定义

在宏所构建的表达式中,可以用 $ 的方式将它插值进去。

macro sayhello()
return :( println("Hello, world!") )
end

为了保持卫生,宏中的变量被分为局域和全局的:如果被赋值、声称局域或用于函数实参名称,则认为是局域的,否则是全局的。局域变量被重命名为唯一的,全局变量在宏定义的环境中解释。

有些情况下,变量可能不希望这样被解析,所以需要用到 esc 来让局域变量保持原样展开。

宏可以定义多个方法,但需要注意是根据 AST 的类型而非值的类型派发。

调用

@name expr1 expr2 ...
@name(expr1, expr2, ...)
@name[a b] * v

实例

julia> macro sayhello(name)
return :( println("Hello, ", $name) )
end
@sayhello (macro with 1 method)

julia> ex = macroexpand(Main, :(@sayhello("human")) )
:(Main.println("Hello, ", "human"))

julia> @macroexpand @sayhello "human"
:(Main.println("Hello, ", "human"))

性质

相关内容

宏看起来像是表达式的函数,但其区别在于宏对表达式的操作是在编译期发生的,在程序运行之前就已经生成了代码。

参考文献